﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Reflection;
using QUT.Bio.SilverMap.ObjectModel;
using QUT.Bio.Util;

#if ! SILVERLIGHT
using System.Windows.Navigation;
#endif

namespace QUT.Bio.SilverMap {
	/// <summary>
	/// A HspPanel displays the details of a single Hsp, which is misnamed "Hit" in SilverMap.
	/// </summary>
	public partial class HspPanel: UserControl {
		private Hit hit;
		private int alignmentWidth = 40;

		public HspPanel () {
			InitializeComponent();
		}

		#region Method: Initialise
		/// <summary>
		/// Prepare this HspPanel for use.
		/// </summary>
		/// <param name="hit">The hsp to display.</param>
		/// <param name="alignmentWidth">The character width for the sequence alignment display.</param>
		public void Initialise (
			Hit hit,
			int alignmentWidth
		) {
			this.alignmentWidth = alignmentWidth;
			this.Hit = hit;
		}
		#endregion

		#region Property: AlignmentWidth
		public int AlignmentWidth {
			get {
				return alignmentWidth;
			}
			set {
				alignmentWidth = value;
				Refresh();
			}
		}
		#endregion

		#region Property: Hit
		public Hit Hit {
			get {
				return hit;
			}
			set {
				hit = value;

				Refresh();
			}
		}
		#endregion

		private void Refresh () {
			#region Remove all content in rows below the Identities...
			int lastRow = endStaticFields.GetRow();

			for ( int i = 0; i < layoutRoot.Children.Count; i++ ) {
				UIElement child = layoutRoot.Children[i];
				if ( child.GetRow() > lastRow ) {
					layoutRoot.Children.Remove( child );
				}
			}

			while ( layoutRoot.RowDefinitions.Count > lastRow + 1 ) {
				layoutRoot.RowDefinitions.RemoveAt( layoutRoot.RowDefinitions.Count - 1 );
			}
			#endregion

			#region Set static content
			if ( hit == null ) {
				this.eValueField.Text = "?";
				this.positivesField.Text = "?";
				this.identitiesField.Text = "?";
				this.queryExtentField.Text = "?";
				this.hitExtentField.Text = "?";
			}
			else {
				this.eValueField.Text = hit.EValue.ToString();
				this.positivesField.Text = hit.Positives.ToString();
				this.identitiesField.Text = hit.Identities.ToString();
				this.queryExtentField.Text = hit.QueryFrom + ".." + hit.QueryTo;
				this.hitExtentField.Text = hit.HitFrom + ".." + hit.HitTo;
			}
			#endregion

			#region Add dynamically displayed fields.
			ObjectWrapper w = new ObjectWrapper( hit );

			foreach ( PropertyInfo property in w.DisplayedProperties ) {
				TextBlock header = new TextBlock {
					Style = (Style) Resources["Head"],
					Text = property.Name
				};

				TextBlock text = new TextBlock {
					Style = (Style) Resources["Text"],
					Text = w[property.Name].ToString()
				};
				text.SetColumn( 2 );

				layoutRoot.AddRow( header, text );
			}
			#endregion

			#region Insert new Alignment stuff
			int startPos = 0;

			while ( startPos < hit.QuerySequence.Length ) {
				int length = startPos + alignmentWidth > hit.QuerySequence.Length
				? hit.QuerySequence.Length - startPos
				: alignmentWidth;

				string qFragment = hit.QuerySequence.Substring( startPos, length );
				string mFragment = "";
				
				try { 
					mFragment = hit.Midline == Hit.SEQUENCE_DATA_UNAVAILABLE
					? ""
					: hit.Midline.Substring( startPos, length );
				}
				catch {
				}
				
				string hFragment = hit.HitSequence.Substring( startPos, length );

				TextBlock qLabel = new TextBlock {
					Text = "Query",
					Style = (Style) Resources["Head"],
					HorizontalAlignment = HorizontalAlignment.Right
				};

				TextBlock qText = new TextBlock {
					Text = qFragment,
					TextWrapping = TextWrapping.NoWrap,
					Style = (Style) Resources["Text"]
				};
				qText.SetColumn( 2 );

				layoutRoot.AddRow( qLabel, qText );

				if ( mFragment.Length > 0 ) {
					TextBlock mText = new TextBlock {
						Text = mFragment,
						TextWrapping = TextWrapping.NoWrap,
						Style = (Style) Resources["Text"]
					};
					mText.SetColumn( 2 );

					layoutRoot.AddRow( mText );
				}

				TextBlock hLabel = new TextBlock {
					Text = "Hit",
					Style = (Style) Resources["Head"],
					HorizontalAlignment = HorizontalAlignment.Right
				};

				TextBlock hText = new TextBlock {
					Text = qFragment,
					TextWrapping = TextWrapping.NoWrap,
					Style = (Style) Resources["Text"]
				};
				hText.SetColumn( 2 );

				layoutRoot.AddRow( hLabel, hText );

				layoutRoot.RowDefinitions.Add( new RowDefinition {
					Height = new GridLength( 10 )
				} );

				startPos += alignmentWidth;
			}

			#endregion
		}
	}
}
